using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Web;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;
using DotNetNuke.Security.Roles;
using DotNetNuke.Services.Localization;
using pnc.Publisher.Content;

namespace ITCrossing
{
	public class metaPostMagicContentProvider : IPublishable
	{
		private PortalSettings _portalSettings;

		# region IPublishable Members

		# region Public Properties
		
		/// <summary>
		/// ProviderKey should be set to the Friendly Name of the module for
		/// which this provider is being implemented.
		/// </summary>
		public string ProviderKey
		{
			get
			{
				return MetaPostServices.GetFriendlyNameFromModuleDefinition("pnc: Content");
			}
		}

		/// <summary>
		/// ManifestPath is the path to the manifest file used to determine 
		/// the settings available in Windows Live Writer.  An example path might
		/// be /DesktopModules/itcMetaPost/manifests/wlwblog.xml.  See the following URL for 
		/// information regarding what Content can be placed in a WLW manifest file:
		/// http://msdn2.microsoft.com/en-us/library/bb463260.aspx
		/// </summary>
		public string ManifestFilePath
		{
			get { return "/DesktopModules/itcMetaPost/manifests/wlwmagiccontent.xml"; }
		}

		/// <summary>
		/// LocalizationFilePath is the path including the filename to the 
		/// resource file used by metaPost to retrieve the error messages
		/// shown to the user (eg. "/DesktopModules/itcMetaPost/App_LocalResources/itcMetaPost")
		/// </summary>
		public string LocalizationFilePath
		{
			get { return "/DesktopModules/itcMetaPost/App_LocalResources/itcMetaPostMagicContent"; }
		}

		/// <summary>
		/// OPTIONAL - ImageUploadPath is a property metaPost uses to determine where 
		/// to store the media files (images).  This property should return just a 
		/// section of the path starting from the portal root.  Added to this path will
		/// be the username along with the path 
		/// </summary>
		public string ImageUploadPath
		{
			get
			{
				// This can be overridden with custom implementation if needed.  If
				// overridden, then a message should be placed in the ImagePath column
				// for your provider letting administrators know that administration of
				// the ImagePath is implemented elsewhere.  
				return MetaPostServices.GetProviderImageUploadPath(ProviderKey);
			}
		}

		/// <summary>
		/// AttachmentUploadPath is used to specify the location of attachments added
		/// to a post or page.
		/// </summary>
		public string AttachmentUploadPath
		{
			get
			{
				// For now, we'll just set this to the same as the image upload path
				return MetaPostServices.GetProviderAttachmentUploadPath(ProviderKey);
			}
		}

		/// <summary>
		/// SettingsUserControlPath is for future use.  It will return the path to the
		/// the settings user control for this provider.  
		/// </summary>
		public string SettingsUserControlPath
		{
			get { throw new NotImplementedException(); }
		}

		# endregion

		# region Get Methods

		/// <summary>
		/// The purpose of this procedure is to provide a list of all the modules in a 
		/// given portal to which the currently logged on user has either insert, update
		/// or delete access.  Note, this may not always correspond to an actual module.
		/// For example, with the DNN Blog module provider, a list of blogs is returned
		/// along with URL of where each blog is available within the site.  For the News
		/// Articles module, we return a list of all News Articles modules that have been
		/// added to Tabs throughout the site.
		/// </summary>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		/// <param name="providerKey"></param>
		public ModuleInfoStruct[] GetModulesForUser(UserInfo userInfo, PortalSettings portalSettings, string providerKey)
		{
			ModuleInfoStruct[] infoArray = new ModuleInfoStruct[1];

			ModuleInfoStruct moduleInfo = new ModuleInfoStruct();
			moduleInfo.ModuleLevelId = portalSettings.PortalId.ToString();
			moduleInfo.ModuleName = portalSettings.PortalName + " - " + providerKey;
			moduleInfo.Url = MetaPostServices.GetRedirectUrl(providerKey, portalSettings.HomeTabId); 

			infoArray[0] = moduleInfo;

			return infoArray;
		}

		/// <summary>
		/// GetRecentItems returns a list of the recent items added to the module.  For example, with
		/// the blog module, the list would return all the recent blog entries.  For the Text/HTML provider, 
		/// this method would return a list of the recently added Text/HTML modules in the site.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="numberOfItems"></param>
		/// <param name="requestType">GetRecentItems can be called for a number of reasons.  In Windows Live Writer,
		/// users are able to retrieve a list of recent posts or recent pages.  The requestType parameter is used
		/// to denote whether a list of pages or posts is being requested.  Additionally, WLW may request a list 
		/// of hiearchical pages to show pages when allowing a parent page to be assigned to a new page.  The values for this enum
		/// are RecentPosts, RecentPages and RecentPagesHiearchical.</param>
		/// <param name="providerKey"></param>
		/// <returns></returns>
		public Item[] GetRecentItems(string moduleLevelId, UserInfo userInfo, PortalSettings portalSettings, int numberOfItems, RecentItemsRequestType requestType, string providerKey)
		{
			List<Item> itemArray = new List<Item>();

			// List used to retrieve an array of ModuleInfoStructs to return to metaPost.
			List<ModuleInfoStruct> moduleInfoList = new List<ModuleInfoStruct>();

			// dnnModuleInfos is the list which stores the DnnModuleInfoStructs returned from 
			List<DnnModuleInfoStruct> dnnModuleInfos
				= MetaPostServices.GetEditableModules(providerKey, userInfo.UserID, portalSettings.PortalId);

			if (dnnModuleInfos.Count > 0)
			{
				int itemCount = 0;
				foreach (DnnModuleInfoStruct dnnModuleInfo in dnnModuleInfos)
				{
					// Loop through the modules and retrieve the locale and role info for all entries
					ContentController contentController = new ContentController();
					ArrayList contentEntries = contentController.GetContentByModule(dnnModuleInfo.ModuleId);

					// Retrieve the module settings needed to retrieve the title 
					ModuleController moduleController = new ModuleController();
					Hashtable moduleSettings = moduleController.GetModuleSettings(dnnModuleInfo.ModuleId);

					foreach (ContentInfo cInfo in contentEntries)
					{
						Item item = new Item();
						string title = GetModuleTitle(moduleSettings, cInfo.Locale);
						string genericRole =
							MetaPostServices.GetString("GenericRole", "All Visitors", LocalizationFilePath, portalSettings.DefaultLanguage);
						string role = cInfo.Role.Replace("GENERIC", genericRole);
						item.ItemId = cInfo.ItemId;
						string modulePath = dnnModuleInfo.TabPath.Replace("//", "/");
						// remove the beginning forward slash
						if (modulePath.Length > 1 && modulePath.Substring(0, 1) == "/")
							modulePath = modulePath.Substring(1);
						item.Title = cInfo.Locale + " - " + role + " - " + title; // +" (" + modulePath + ")";
						item.Content = title + " ";
						item.DateCreated = cInfo.CreatedDate;
						// Configure the URL that WLW uses to send the user to after a post has been made
						// We will make use of MetaPostRedirect here to 
						item.Link = Globals.NavigateURL(dnnModuleInfo.TabId);
						itemArray.Add(item);
						itemCount++;
						if (itemCount >= numberOfItems) break;
					}
				}
			}
			else
			{
				throw new MetaPostException("NoModulesForUser",
											"There are no Magic Content modules associated with this user account.  Please enter a user account which has been associated with a blog.");
			}

			return itemArray.ToArray();
		}

		/// <summary>
		/// GetItem is used to retrieve a specific item, which may be a page or a post if your module supports
		/// both concepts.  In cases where a module supports both pages and posts, a concept made available in 
		/// Windows Live Writer, but not in Word 2007 or in many other publishing clients, the itemType parameter 
		/// can be used to distinguish between when this method is being called to add a page or a post.  If your 
		/// provider doesn't support a distinction between pages and posts, then simply ignore the itemType parameter.
		/// </summary>
		/// <param name="itemId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="itemType"></param>
		/// <returns></returns>
		public Item GetItem(string itemId, UserInfo userInfo, PortalSettings portalSettings, ItemType itemType)
		{
			Item item = new Item();
			
			ContentController contentController = new ContentController();
			ContentInfo contentInfo = contentController.GetContentByID(Convert.ToInt32(itemId));
			
			List<string> settingsCats = new List<string>();

			//Show the modules settings
			ModuleController mc = new ModuleController();
			Hashtable moduleSettings = mc.GetModuleSettings(contentInfo.ModuleId);

			if (moduleSettings["PNC_CONTENT_HIDEFORREGISTERED"] != null &&
				moduleSettings["PNC_CONTENT_HIDEFORREGISTERED"].ToString()  == "True")
			{
				settingsCats.Add(MetaPostServices.GetString("HideContent", "Hide for Registered", LocalizationFilePath, portalSettings.DefaultLanguage));
			}
			if (moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_BY"] != null &&
				moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_BY"].ToString() == "True")
			{
				settingsCats.Add(MetaPostServices.GetString("ShowLastUpdatedBy", "Show Last Updated By", LocalizationFilePath, portalSettings.DefaultLanguage));
			}
			if (moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_AT"] != null &&
				moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_AT"].ToString() == "True")
			{
				settingsCats.Add(MetaPostServices.GetString("ShowLastUpdatedOn", "Show Last Updated On", LocalizationFilePath, portalSettings.DefaultLanguage));
			}

			// Show the Role and Locale using the categories
			string genericRole =
			MetaPostServices.GetString("GenericRole", "All Visitors", LocalizationFilePath, portalSettings.DefaultLanguage);
			string role = contentInfo.Role.Replace("GENERIC", genericRole);
			settingsCats.Add(role);
			settingsCats.Add(contentInfo.Locale);
			
			item.Categories = settingsCats.ToArray();
			item.Title = GetModuleTitle(contentInfo.ModuleId, contentInfo.Locale);
			
			_portalSettings = portalSettings;
			item.Content = ProcessFileIds(HttpUtility.HtmlDecode(contentInfo.Content));
			item.DateCreated = contentInfo.CreatedDate;
			item.ItemId = contentInfo.ItemId;

			return item;
		}

		# endregion

		# region Add, Edit and Delete Methods

		/// <summary>
		/// EditItem is called to edit either a page or a post.  The difference
		/// between the two is denoted in a property of the Item struct (ItemType).
		/// An additional property of the Item struct that may be important to the 
		/// implementation of the EditItem method is the Publish property.  This is 
		/// set to true when the item should be published.  The default setting of 
		/// false denotes that the item may be saved as a draft.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="item"></param>
		/// <returns></returns>
		public bool EditItem(string moduleLevelId, UserInfo userInfo, PortalSettings portalSettings, Item item)
		{
			ContentController contentController = new ContentController();
			ContentInfo contentInfo = null;
			contentInfo = contentController.GetContentByID(Convert.ToInt32(item.ItemId));
			ModuleController moduleController = new ModuleController();

			List<string> images = MetaPostServices.GetImageListFromItem(ref item);

			UpdateModuleSettingsPassedThroughCategories(item.Categories, contentInfo.ModuleId, portalSettings);

			MetaPostServices.SaveItemImages(Convert.ToInt32(item.ItemId), images, ProviderKey, portalSettings, userInfo.UserID);

			_portalSettings = portalSettings;
			// Change the Image URLs for all added images.
			string regex = @"(?<firstpart><img[^>]+?src="")(?<src>" + portalSettings.HomeDirectory + @"[^""]+?)(?<thirdpart>""[^>]*?>)";
			RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase;
			item.Content =
				Regex.Replace(item.Content, regex, new MatchEvaluator(ReplaceImageTokens), options);
			
			// Normally, the save operation occurs before SaveItemImages, but for this module, we want to replace
			// the image URLs with a [PORTALFILEID=XXX] token.
			UpdateContentAndTitle(contentInfo, item.Title, HttpUtility.HtmlEncode(item.Content), ref portalSettings);


			// Set the redirect URL so the page is shown in the browser after the update completes.
			SetTempInstallUrl(contentInfo, moduleController);

			return true;

		}

		/// <summary>
		/// NewItem is used for creating new items (either pages or posts).  The implementation 
		/// in your provider can distinguish between page and post requests for NewItem by the 
		/// ItemType property of the Item struct.  Additional properties of the Item Struct which 
		/// may be of interest in the implmentation of this method are: Publish, StyleDetectionPost,StyleId, and ItemType.
		/// See the comments associated with each of these properties of the Item struct for more information.
		/// </summary>
		/// <param name="moduleLevelId">String - ModuleId is a very loose concept here.  Anything can be tracked in this variable as long as it is consistent.  For the Blog module, the BlogId is passed and for the Text/HTML module, the ModuleId is passed and for the Ventrian News Articles module, the ArticleId is passed.  This value is based on the value sent to Windows Live Writer when GetModulesForUser is called. </param>
		/// <param name="userInfo">DotNetNuke UserInfo object.  This UserInfo object is retrieved by metaPost and made available to every method call in the MetaPostProvider interface.</param>
		/// <param name="portalSettings">DotNetNuke PortaSettings object - This is provided to make it easier to work with metaPost.  metaPost does all the work behind the scenes of identifying the right portalSettings object based on the requested URL.</param>
		/// <param name="item">Custom Struct - The item struct contains a list of fields sent through the MetaWeblog API.  The properties have been renamed to make sense in more general applications outside of just blogs.</param>
		/// <returns></returns>
		public string NewItem(string moduleLevelId, UserInfo userInfo, PortalSettings portalSettings, Item item)
		{

			List<string> images = MetaPostServices.GetImageListFromItem(ref item);

			string newId = string.Empty;

			if (item.StyleDetectionPost)
			{
				try
				{

					ModuleController moduleController = new ModuleController();
					
					ContentInfo contentInfo = GetContentInfoFromStyleId(Convert.ToInt32(item.StyleId), portalSettings);

					if (item.StyleDetectionPost)
					{
						string existingTitle = GetModuleTitle(contentInfo.ModuleId, contentInfo.Locale);
						MetaPostServices.SetTempStyleValue(userInfo.UserID, "styleId", item.StyleId);
						MetaPostServices.SetTempStyleValue(userInfo.UserID, "content", contentInfo.Content);
						MetaPostServices.SetTempStyleValue(userInfo.UserID, "title", existingTitle);
					}

					UpdateContentAndTitle(contentInfo, item.Title, item.Content, ref portalSettings);

					// We set a TempInstallUrl since this is used by metaPost to redirect to the right
					// page when performing style detection.
					# region Code to call SetTempInstallUrl
					SetTempInstallUrl(contentInfo, moduleController);

					# endregion

					newId = contentInfo.ItemId.ToString();

				}
				catch (Exception ex)
				{
					// No problem if we fail, the template just won't be available.
					throw ex;
				}
			}
			else
			{
				throw new MetaPostException("AddNotImplemented", "Adding a new item is not currently supported with the Magic Content provider.  To edit content, open an existing item.");
			}

			MetaPostServices.SaveItemImages(Convert.ToInt32(newId), images, ProviderKey, portalSettings, userInfo.UserID);

			return newId;
		}

		/// <summary>
		/// DeleteItem is used to delete either a page or a post.  The difference between the two is noted 
		/// in the itemType parameter which is an enumeration set to either Page or Post.
		/// </summary>
		/// <param name="itemId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <param name="itemType"></param>
		/// <returns></returns>
		public bool DeleteItem(string itemId, UserInfo userInfo, PortalSettings portalSettings, ItemType itemType)
		{
			// Check to see if a temporary style post was made and needs to be restored.
			string styleId = string.Empty;
			string styleText = string.Empty;
			string styleTitle = string.Empty;

			try
			{
				styleId = MetaPostServices.GetTempStyleValue(userInfo.UserID, "styleId");
				styleText = MetaPostServices.GetTempStyleValue(userInfo.UserID, "content");
				styleTitle = MetaPostServices.GetTempStyleValue(userInfo.UserID, "title");
				
				// Check to make sure the styleText isn't null or empty
				if (string.IsNullOrEmpty(styleText)) styleText = "";
			} catch {} // Ignore any failures.

			if (!string.IsNullOrEmpty(styleId))
			{
				try
				{
					
					// We will simply restore the text from the old version by retrieving it and 
					ContentController contentController = new ContentController();
					ContentInfo contentInfo = contentController.GetContentByID(Convert.ToInt32(itemId));
					UpdateContentAndTitle(contentInfo, styleTitle, styleText,ref portalSettings);
					
				} catch {} // Ignore failure.
			}
			else
			{
				throw new MetaPostException("DeleteNotImplemented",
											"Deleting an item is not currently supported with the Magic Content provider.  You may use the web interface to delete a Magic Content module from a page.");
			}

			return true;
		}

		# endregion

		# region Category Related Procedures

		/// <summary>
		/// GetCategories retrieves a list of categories for a particular module.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		public ItemCategoryInfo[] GetCategories(string moduleLevelId, UserInfo userInfo,
												PortalSettings portalSettings)
		{

			ItemCategoryInfo[] categories = null;

			// Get the actual ModuleId since we're tracking the TabModuleId in the moduleLevelId parameter
			//DnnModuleInfoStruct moduleInfo = MetaPostServices.GetModuleInfo(Convert.ToInt32(moduleLevelId));
			//int articleModuleId = moduleInfo.ModuleId;

			// Get the list of Roles
			RoleController roleController = new RoleController();
			ArrayList roles = roleController.GetPortalRoles(portalSettings.PortalId);

			// Get the list of supported locales
			LocaleCollection locales = Localization.GetEnabledLocales();

			int listCount = 7 + locales.Count + roles.Count;

			categories = new ItemCategoryInfo[listCount];
			ItemCategoryInfo settingsCategory;
			// Add the Settings Categories
			settingsCategory = new ItemCategoryInfo();
			settingsCategory.CategoryId = 2000001;
			settingsCategory.CategoryName = MetaPostServices.GetString("ModuleSettings", "Module Settings", LocalizationFilePath, portalSettings.DefaultLanguage);
			settingsCategory.Description = settingsCategory.CategoryName;
			settingsCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			categories[0] = settingsCategory;

			settingsCategory = new ItemCategoryInfo();
			settingsCategory.CategoryId = 2000002;
			settingsCategory.CategoryName = MetaPostServices.GetString("HideContent", "Hide for Registered", LocalizationFilePath, portalSettings.DefaultLanguage);
			settingsCategory.Description = settingsCategory.CategoryName;
			settingsCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.ParentId = 2000001;
			categories[1] = settingsCategory;

			settingsCategory = new ItemCategoryInfo();
			settingsCategory.CategoryId = 2000003;
			settingsCategory.CategoryName = MetaPostServices.GetString("ShowLastUpdatedBy", "Show Last Updated By", LocalizationFilePath, portalSettings.DefaultLanguage);
			settingsCategory.Description = settingsCategory.CategoryName;
			settingsCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.ParentId = 2000001;
			categories[2] = settingsCategory;

			settingsCategory = new ItemCategoryInfo();
			settingsCategory.CategoryId = 2000004;
			settingsCategory.CategoryName = MetaPostServices.GetString("ShowLastUpdatedOn", "Show Last Updated On", LocalizationFilePath, portalSettings.DefaultLanguage);
			settingsCategory.Description = settingsCategory.CategoryName;
			settingsCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.ParentId = 2000001;
			categories[3] = settingsCategory;

			settingsCategory = new ItemCategoryInfo();
			settingsCategory.CategoryId = 2000005;
			settingsCategory.CategoryName = MetaPostServices.GetString("Roles", "Roles", LocalizationFilePath, portalSettings.DefaultLanguage);
			settingsCategory.Description = settingsCategory.CategoryName;
			settingsCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			categories[4] = settingsCategory;

			settingsCategory = new ItemCategoryInfo();
			settingsCategory.CategoryId = 2000007;
			settingsCategory.CategoryName = MetaPostServices.GetString("GenericRole", "All Visitors", LocalizationFilePath, portalSettings.DefaultLanguage);
			settingsCategory.Description = settingsCategory.CategoryName;
			settingsCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.ParentId = 2000005;
			categories[5] = settingsCategory;

			settingsCategory = new ItemCategoryInfo();
			settingsCategory.CategoryId = 2000006;
			settingsCategory.CategoryName = MetaPostServices.GetString("Locales", "Locales", LocalizationFilePath, portalSettings.DefaultLanguage);
			settingsCategory.Description = settingsCategory.CategoryName;
			settingsCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			settingsCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
			categories[6] = settingsCategory;

			int i = 7;
			foreach (RoleInfo role in roles)
			{
				// Add the Categories Category
				ItemCategoryInfo categoriesCategory = new ItemCategoryInfo();
				categoriesCategory.CategoryId = 1111 + role.RoleID;
				// Note that if the value in the second argument changes, please update the GetCategoriesToExclude
				// and ProcessExcludeCategories procedures below.
				categoriesCategory.CategoryName = role.RoleName;
				categoriesCategory.Description = categoriesCategory.CategoryName;
				categoriesCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
				categoriesCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
				categoriesCategory.ParentId = 2000005;
				categories[i] = categoriesCategory;
				i++;
			}

			foreach (string locKey in locales.Keys)
			{
				Locale loc = locales[locKey];
				// Add the Categories Category
				ItemCategoryInfo categoriesCategory = new ItemCategoryInfo();
				System.Globalization.CultureInfo info =
					System.Globalization.CultureInfo.CreateSpecificCulture(loc.Code);
				categoriesCategory.CategoryId = 9999 + info.LCID;
				// Note that if the value in the second argument changes, please update the GetCategoriesToExclude
				// and ProcessExcludeCategories procedures below.
				categoriesCategory.CategoryName = loc.Code;
				categoriesCategory.Description = categoriesCategory.CategoryName;
				categoriesCategory.HtmlUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
				categoriesCategory.RssUrl = "http://www.itcrossing.com/" + settingsCategory.CategoryId.ToString();
				categoriesCategory.ParentId = 2000006;
				categories[i] = categoriesCategory;
				i++;
			}

			return categories;
		}

		public bool SetItemCategories(string itemId, ItemCategory[] itemCategories, UserInfo userInfo,
		                        PortalSettings portalSettings)
		{
			// Not yet implemented.
			return true;
		}

		public ItemCategory[] GetItemCategories(string itemId, UserInfo userInfo,
		                                        PortalSettings portalSettings)
		{

			ContentController contentController = new ContentController();
			ContentInfo contentInfo = contentController.GetContentByID(Convert.ToInt32(itemId));
			ItemCategory ic;

			List<ItemCategory> itemCategories = new List<ItemCategory>();

			//Show the modules settings
			ModuleController mc = new ModuleController();
			Hashtable moduleSettings = mc.GetModuleSettings(contentInfo.ModuleId);

			if (moduleSettings["PNC_CONTENT_HIDEFORREGISTERED"] != null &&
				moduleSettings["PNC_CONTENT_HIDEFORREGISTERED"].ToString() == "True")
			{
				ic = new ItemCategory();
				ic.CategoryId = "2000002";
				ic.CategoryName =
					MetaPostServices.GetString("HideContent", "Hide for Registered", LocalizationFilePath, portalSettings.DefaultLanguage);
				itemCategories.Add(ic);
			}
			if (moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_BY"] != null &&
				moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_BY"].ToString() == "True")
			{
				ic = new ItemCategory();
				ic.CategoryId = "2000003";
				ic.CategoryName =
					MetaPostServices.GetString("ShowLastUpdatedBy", "Show Last Updated By", LocalizationFilePath, portalSettings.DefaultLanguage);
				itemCategories.Add(ic);
			}
			if (moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_AT"] != null &&
				moduleSettings["PNC_CONTENT_SHOWLASTUPDATED_AT"].ToString() == "True")
			{
				ic = new ItemCategory();
				ic.CategoryId = "2000004";
				ic.CategoryName =
					MetaPostServices.GetString("ShowLastUpdatedOn", "Show Last Updated On", LocalizationFilePath, portalSettings.DefaultLanguage);
				itemCategories.Add(ic);
			}

			// Show the Role and Locale using the categories
			string genericRole =
			MetaPostServices.GetString("GenericRole", "All Visitors", LocalizationFilePath, portalSettings.DefaultLanguage);
			string role = contentInfo.Role.Replace("GENERIC", genericRole);

			// Get the list of Roles
			RoleController roleController = new RoleController();
			ArrayList roles = roleController.GetPortalRoles(portalSettings.PortalId);

			// Loop through the roles until we find the role
			foreach (RoleInfo r in roles)
			{
				if (r.RoleName == "GENERIC")
				{
					ic = new ItemCategory();
					ic.CategoryId = "2000007";
					ic.CategoryName =
						MetaPostServices.GetString("GenericRole", "All Visitors", LocalizationFilePath, portalSettings.DefaultLanguage);
					itemCategories.Add(ic);
				}
				else if(r.RoleName == contentInfo.Role)
				{
					ic = new ItemCategory();
					ic.CategoryId = "1111" + r.RoleID.ToString();
					ic.CategoryName =
						r.RoleName;
					itemCategories.Add(ic);
				}
			}

			// Set the Locale
			ic = new ItemCategory();
			System.Globalization.CultureInfo info =
					System.Globalization.CultureInfo.CreateSpecificCulture(contentInfo.Locale);
			ic.CategoryId = "9999" + info.LCID;
			ic.CategoryName = info.Name;
			itemCategories.Add(ic);

			return itemCategories.ToArray();
		}

		/// <summary>
		/// Used to add a new category for modules which support this feature.
		/// </summary>
		/// <param name="moduleLevelId"></param>
		/// <param name="userInfo"></param>
		/// <param name="portalSettings"></param>
		/// <returns></returns>
		public int NewCategory(string moduleLevelId, NewItemCategory category, UserInfo userInfo, PortalSettings portalSettings)
		{
			int categoryId = 0;
			// Check first to see if the user should have the ability to add Categories

			ModuleController moduleController = new ModuleController();
			//ModuleInfo moduleInfo =
			//    moduleController.getm(portalSettings.PortalId, moduleName);
			//bool bHasAdminRights = PortalSecurity.IsInRoles(_moduleConfiguration.AuthorizedEditRoles);
			//Dim blnHasModuleEditPermissions As Boolean = PortalSecurity.IsInRoles(_moduleConfiguration.AuthorizedEditRoles)
			throw new MetaPostException("FeatureNotImplemented",
										"This feature is currently not implemented.");

			return categoryId;
		}

		# endregion

		#endregion

		# region Private Procedures Specific to Magic Content Module

		private ContentInfo		GetContentInfoFromStyleId(int moduleId, PortalSettings portalSettings)
		{
			string locCode = string.Empty;
			string role = string.Empty;
			CultureInfo defaultInfo = GetDefaultCultureInfo(portalSettings);
			ContentController contentController = new ContentController();
			ContentInfo defaultContent = new ContentInfo();

			ArrayList items = contentController.GetContentByModule(moduleId);

			foreach (ContentInfo cInfo in items)
			{
				if (cInfo.Role == "GENERIC" && cInfo.Locale == defaultInfo.Name)
				{
					defaultContent = cInfo;
				}
			}

			return defaultContent;
			
		}
		private CultureInfo		GetDefaultCultureInfo(PortalSettings portalSettings)
		{
			// Get default localization info
	
			CultureInfo info = CultureInfo.CreateSpecificCulture(portalSettings.DefaultLanguage);

			return info;
		}
		private string			GetFileIDString(string strFile)
		{

			strFile = strFile.Replace("%20", " ");

			// Remove HomeDirectory from the image file URL
			if (strFile.StartsWith(_portalSettings.HomeDirectory))
			{
				strFile = strFile.Substring(_portalSettings.HomeDirectory.Length);
			}

			DotNetNuke.Services.FileSystem.FileController objFileController = new DotNetNuke.Services.FileSystem.FileController();
			DotNetNuke.Services.FileSystem.FileInfo objFile;

			objFile = objFileController.GetFile(RemoveTrailingSlash(strFile), _portalSettings.PortalId);
			if (objFile == null)
			{
				try
				{
					this.SynchronizePortalStore(_portalSettings.PortalId, _portalSettings.AdministratorRoleId, _portalSettings.HomeDirectoryMapPath);
					//FileSystemUtils.Synchronize(PortalId, objPortal.AdministratorRoleId, objPortal.HomeDirectoryMapPath)
					objFile = objFileController.GetFile(RemoveTrailingSlash(strFile), _portalSettings.PortalId);
				}
				catch
				{
				}
				objFile = objFileController.GetFile(RemoveTrailingSlash(strFile), _portalSettings.PortalId);
			}

			string strFileToken;
			if (objFile != null)
			{
				strFileToken = "[PORTALFILEID=" + objFile.FileId.ToString() + "]";
			}
			else
			{
				strFileToken = strFile;
			}
			return strFileToken;

		}
		private string			GetFilePath(int FileID)
		{

			DotNetNuke.Services.FileSystem.FileInfo ImageFile;
			DotNetNuke.Services.FileSystem.FileController FileController = new DotNetNuke.Services.FileSystem.FileController();
			ImageFile = FileController.GetFileById(FileID, _portalSettings.PortalId);
			if (ImageFile != null)
			{

				string strDomainName = "http://" + HttpContext.Current.Request.Url.Host;

				//Magic Content always uses fully qualified urls for supporting the ability to send email
				return strDomainName + _portalSettings.HomeDirectory + ImageFile.Folder + ImageFile.FileName;
			}
			else
			{
				return string.Empty;
			}

		}
		private string			GetModuleTitle(Hashtable moduleSettings, string locale)
		{
			CultureInfo info = CultureInfo.CreateSpecificCulture(locale);
			string title = moduleSettings["PNC_CONTENT_MODULETITLE_" + info.LCID.ToString()] as string;
			return title ?? string.Empty;
		}
		private string			GetModuleTitle(int moduleId, string locale)
		{
			// Retrieve the module settings needed to retrieve the title 
			ModuleController moduleController = new ModuleController();
			Hashtable moduleSettings = moduleController.GetModuleSettings(moduleId);
			return GetModuleTitle(moduleSettings, locale);
		}
		private string			ProcessFileIds(string content)
		{
			
			string regex = @"\[PORTALFILEID=(?<fileid>\d+)\]";
			RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Singleline;

			content = Regex.Replace(content, regex, new MatchEvaluator(ReplaceFileIds), options);
			

			return content;
		}
		private string			RemoveTrailingSlash(string strFilePath)
		{

			if (strFilePath.IndexOf("/") == 0)
			{
				return strFilePath.Substring(1);
			}
			else
			{
				return strFilePath;
			}
		}
		private string			ReplaceFileIds(Match match)
		{
			int fileId = Convert.ToInt32(match.Groups["fileid"].Value);
			return GetFilePath(fileId);
		}
		private string			ReplaceImageTokens(Match match)
		{
			string content;
			string url = match.Groups["src"].Value;
			string firstPart = match.Groups["firstpart"].Value;
			string thirdPart = match.Groups["thirdpart"].Value;

			content = firstPart + GetFileIDString(url) + thirdPart;

			return content;
		}
		private void			SetTempInstallUrl(ContentInfo contentInfo, ModuleController moduleController)
		{
			ModuleInfo moduleInfo = moduleController.GetModule(contentInfo.ModuleId, Null.NullInteger, false);

			// Make sure the right locale is included in the URL
			string url =
				Globals.NavigateURL(moduleInfo.TabID, string.Empty,
									new string[] { "language=" + contentInfo.Locale });
			string localeString;
			int urlLength = url.Length;
			// Take the right one out (Friendly Format)
			url = url.Replace("language/" + contentInfo.Locale + "/", "_loc_to_use_");
			if (url.Length != urlLength)
			{
				localeString = "language/" + contentInfo.Locale + "/";
			}
			else
			{
				// Take the right one out (QueryString URL Format)
				url = url.Replace("&language=" + contentInfo.Locale, "_loc_to_use_");
				localeString = "&language=" + contentInfo.Locale;
			}
			// Remove what's left
			url = Regex.Replace(url, "((language/[^/]+?/)|(&language=[^$|&]+))", string.Empty, RegexOptions.Singleline | RegexOptions.IgnoreCase);
			// Place the right one back in
			url = url.Replace("_loc_to_use_", localeString);

			MetaPostServices.SetTempInstallUrl(ProviderKey, url);
		}
		public	void			SynchronizePortalStore(int PortalId, int AdministratorRoleId, string HomeDirectory)
		{

			string tmp = HomeDirectory + "\\diurhhgftgtahfgtrgfd";
			System.IO.Directory.CreateDirectory(tmp);
			if (System.IO.Directory.Exists(tmp))
			{
				System.IO.Directory.Delete(tmp);
			}

			FileSystemUtils.Synchronize(PortalId, AdministratorRoleId, HomeDirectory);

		}
		private void			UpdateContentAndTitle(ContentInfo contentInfo, string title, string content, ref PortalSettings portalSettings)
		{


			CultureInfo info = CultureInfo.CreateSpecificCulture(contentInfo.Locale);

			// Retrieve the title for the module

			contentInfo.Content = content;

			ContentController objContentController = new ContentController();
			objContentController.UpdateContent(contentInfo);

			ModuleController objModuleSettings = new ModuleController();

			objModuleSettings.UpdateModuleSetting(contentInfo.ModuleId, "PNC_CONTENT_MODULETITLE_" + Convert.ToString(info.LCID), title);

		}
		private void UpdateModuleSettingsPassedThroughCategories(string[] categories, int moduleId, PortalSettings portalSettings)
		{
			ModuleController moduleController = new ModuleController();
			bool hide = false, showby = false, showon = false;

			if (categories != null)
			{
				foreach (string cat in categories)
				{
					if (cat == MetaPostServices.GetString("HideContent", "Hide for Registered", LocalizationFilePath, portalSettings.DefaultLanguage))
						hide = true;
					if (cat == MetaPostServices.GetString("ShowLastUpdatedBy", "Show Last Updated By", LocalizationFilePath, portalSettings.DefaultLanguage))
						showby = true;
					if (cat == MetaPostServices.GetString("ShowLastUpdatedOn", "Show Last Updated On", LocalizationFilePath, portalSettings.DefaultLanguage))
						showon = true;
				}
			}
			moduleController.UpdateModuleSetting(moduleId, "PNC_CONTENT_HIDEFORREGISTERED", hide.ToString());
			moduleController.UpdateModuleSetting(moduleId, "PNC_CONTENT_SHOWLASTUPDATED_BY", showby.ToString());
			moduleController.UpdateModuleSetting(moduleId, "PNC_CONTENT_SHOWLASTUPDATED_AT", showon.ToString());
		}

		# endregion

	}
}